// src/hooks/useSaveImage.ts
import { ref, readonly } from "vue";

class ImageSaver {
  protected _isSaving = ref(false);

  public get isSaving() {
    return readonly(this._isSaving);
  }

  private showToast(title: string) {
    uni.showToast({ title, icon: "none", duration: 2000 });
  }

  /**
   * 保存网络图片到相册
   * @param url 图片网络地址
   */
  async saveImage(url: string): Promise<void> {
    if (this._isSaving.value) return;
    if (!url) {
      this.showToast("图片地址不能为空");
      return;
    }

    this._isSaving.value = true;

    try {
      const tempPath = await this.downloadImage(url);
      await this.saveToAlbum(tempPath);
      this.showToast("保存成功");
    } catch (error: any) {
      this.handleError(error);
    } finally {
      this._isSaving.value = false;
    }
  }

  private async downloadImage(url: string): Promise<string> {
    try {
      const { tempFilePath } = await uni.downloadFile({ url });
      if (!tempFilePath) throw new Error("图片下载失败");
      return tempFilePath;
    } catch (error: any) {
      throw new Error(`下载失败: ${error.message || "未知错误"}`);
    }
  }

  private async saveToAlbum(tempPath: string): Promise<void> {
    try {
      await uni.saveImageToPhotosAlbum({ filePath: tempPath });
    } catch (error: any) {
      if (error.errMsg?.includes("auth")) {
        await this.requestAuth();
        // 递归调用需要返回以确保返回 Promise
        return this.saveToAlbum(tempPath);
      }
      throw new Error(`保存失败: ${error.errMsg || error.message}`);
    }
  }

  private async requestAuth(): Promise<void> {
    try {
      const { authSetting } = await uni.openSetting();
      if (!authSetting?.["scope.writePhotosAlbum"]) {
        throw new Error("未获得相册权限");
      }
    } catch (error: any) {
      throw new Error("权限请求失败: " + (error.message || error.errMsg));
    }
  }

  private handleError(error: Error): void {
    console.error("保存图片失败:", error);
    this.showToast(error.message || "保存失败");
  }
}

// 导出hooks函数
export function useSaveImage() {
  const imageSaver = new ImageSaver();

  return {
    isSaving: imageSaver.isSaving,
    saveImage: imageSaver.saveImage.bind(imageSaver),
  };
}
